<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>js数据类型</title>
</head>
<body>
<script>
    //1. 会  背会 学会
    //2. 期望薪资  12-13k 15k 18k
    //3. 25k 面向对象  框架 封装 模块
    //4. 基础好


    //堆栈(内存) 这门语言在内存中的调用和读取

    //JS数据类型都有哪些
    //按照 ECMAScript规范
    /*
    * 基本数据类型(原始值类型/值类型)
    *   number: NaN\Infinity\正常数字
    *   string: 正常字符串\模版字符串
    *   boolean: true\false
    *   null: 空 typeof null ==> "object"
    *   undefined: 未定义
    *   symbol: 唯一值
    *   bigInt: 大数字
    *
    * 引用数据类型(对象数据类型)
    *   在js中Object是一个基类
    *   object:
    *       {}: 空对象
    *       []: Array
    *       /^$/: RegExp
    *       new Date: 日期
    *       ....
    *       function
    * */
   /* //symbol
    let str = "a";
    // "a" === "a" ; true
    // Symbol("a") === Symbol("a");// true?
    let obj = {
        a: 1,
        a: 2
    };
    let obj1 = {
        [Symbol("a")]: 1,
        [Symbol("a")]: 2
    }
    // obj.a = 2*/


    //bigInt
    //后端数据库在定义数字的时候会定义数字的长度
    //JS中是有最大安全数字的(js中的数字是有最大长度限制的)
    console.log(Number.MAX_SAFE_INTEGER);//js中的最大安全数字
    console.log(Number.MIN_SAFE_INTEGER);
    //bigInt数据类型
    // let bigNum = 9007199254740991n;
    // bigNum + 1
    // VM616:1 Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions
    // bigNum + 1n


    //js中所有的可以调用call方法的都可以认为是一个 "可执行对象";
    //可执行对象(普通函数/箭头函数/构造函数/生成器函数)


    //js中常见的数据类型判断
    /*
    * typeof 只能判断基本数据类型(null==>object); 判断引用数据类型 都返回object
    * instanceof 只有知道数据类型才可以判断   语法: 要判断数据类型的变量 instanceof Array
    * constructor 语法: 要判断数据类型的变量.constructor === Array
    * Object.prototype.toString.call() 原生js最全能的数据类型判断 "[object 数据类型]"
    * ------
    * Array.isArray() //数组API
    * Number.isNaN() //是不是 不是一个数  NaN ===> not a number
    * ---
    *   jq ==> $.toType() 自己实现属于自己的toType数据类型判断 Object.toType() ==> "数据类型"
    *           isFunction  是不是一个function  Function.isFunction() ==> 布尔
    *           isEmptyObject 是不是一个空的对象 Object.isEmptyObject() ==> 布尔
    *           isArrayLike 是不是一个类数组 Array.isArrayLike() ==> 布尔
    *           isWindow 是不是window对象 window.isWindow() ==> 布尔
    * */

    Function.prototype.isFunction = function (){
        return true
    }

    Function.isFunction()



    let arr = [];

    // 腾讯经典面试题
    // typeof 运行超过两次以上 最终返回值 都是字符串的 "string"
    // (typeof typeof typeof 1234)  返回值 ==> string


    //typeof null ==> "object" 为什么
    // || 转换
    //C++

    //所有的数据类型 在计算机中都已以二进制方式存储的


    //整数:  1     20数字 ==>二进制  110100
    //字符串: 100
    //布尔: 110
    //对象: 000
    //undefined: -2^30
    //null: 000000

    //只判断二进制的前三位
    // typeof xxx



    /*
    *  *   jq ==> $.toType() 自己实现属于自己的toType数据类型判断 Object.toType() ==> "数据类型"
    *           isFunction  是不是一个function  Function.isFunction() ==> 布尔
    *           isEmptyObject 是不是一个空的对象 Object.isEmptyObject() ==> 布尔
    *           isArrayLike 是不是一个类数组 Array.isArrayLike() ==> 布尔
    *           isWindow 是不是window对象 window.isWindow() ==> 布尔
    *
    *
    * */

    // Object.isEmptyObject = function(){}

    //判断一个变量是否是一个空的{}
    Object.prototype.isEmptyObject = function (arg){
        //如果这个变量不是对象 那么直接返回
        if(arg.constructor !== Object) return false;
        //定义一个flag表示
        let flag = false;
        //遍历当前的对象
        for (let key in arg){
            //在遍历这个对象之前,只需要遍历当前对象的私有属性就好了,如果不是私有属性,就跳过当前循环,进入下一个循环
            if(!arg.hasOwnProperty(key)) continue;
            //如果key值存在那么,就表示这个对象不是一个空的对象
            flag = !!key
        }
        return !flag
    }

    Object.isEmptyObject({a:1}); // false

    //堆栈

</script>
</body>
</html>